package com.och.mrcp.core.mrcp.parser;

import com.och.mrcp.core.mrcp.model.*;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * MRCPv2消息解析器
 */
@Slf4j
public class MrcpMessageParser {
    
    // 第一行解析正则表达式 - 支持标准MRCPv2格式
    // 请求格式：MRCP/2.0 <message-length> <method> <request-id>
    // 响应格式：MRCP/2.0 <message-length> <request-id> <status-code> <status-reason>
    // 事件格式：MRCP/2.0 <message-length> <event-name> <request-id> <request-state>
    private static final Pattern REQUEST_FIRST_LINE_PATTERN = Pattern.compile(
        "^MRCP/(\\d+\\.\\d+)\\s+(\\d+)\\s+([A-Z-]+)\\s+(\\d+)$");
    
    private static final Pattern RESPONSE_FIRST_LINE_PATTERN = Pattern.compile(
        "^MRCP/(\\d+\\.\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(.+)$");
    
    private static final Pattern EVENT_FIRST_LINE_PATTERN = Pattern.compile(
        "^MRCP/(\\d+\\.\\d+)\\s+(\\d+)\\s+([A-Z-]+)\\s+(\\d+)\\s+([A-Z-]+)$");
    
    // 头部字段解析正则表达式
    private static final Pattern HEADER_PATTERN = Pattern.compile(
        "^([^:]+):\\s*(.+)$");
    
    /**
     * 解析MRCP消息字符串
     */
    public static MrcpMessage parse(String message) {
        if (message == null || message.trim().isEmpty()) {
            throw new IllegalArgumentException("Message cannot be null or empty");
        }
        
        String[] lines = message.split("\r\n");
        if (lines.length < 2) {
            throw new IllegalArgumentException("Invalid MRCP message format");
        }
        
        // 解析第一行
        String firstLine = lines[0];
        
        // 尝试解析为请求消息
        Matcher requestMatcher = REQUEST_FIRST_LINE_PATTERN.matcher(firstLine);
        if (requestMatcher.matches()) {
            String version = requestMatcher.group(1);
            String messageLength = requestMatcher.group(2);
            String method = requestMatcher.group(3);
            String requestId = requestMatcher.group(4);
            
            // 验证版本
            if (!"2.0".equals(version)) {
                throw new IllegalArgumentException("Unsupported MRCP version: " + version);
            }
            
            log.debug("Parsed MRCP request - Version: {}, Length: {}, Method: {}, RequestId: {}", 
                    version, messageLength, method, requestId);
            
            // 解析头部，提取资源类型
            MrcpMessage.ResourceType resourceType = parseResourceTypeFromHeaders(lines);
            
            return parseRequest(method, resourceType, lines, requestId);
        }
        
        // 尝试解析为响应消息
        Matcher responseMatcher = RESPONSE_FIRST_LINE_PATTERN.matcher(firstLine);
        if (responseMatcher.matches()) {
            String version = responseMatcher.group(1);
            String messageLength = responseMatcher.group(2);
            String requestId = responseMatcher.group(3);
            String statusCode = responseMatcher.group(4);
            String statusReason = responseMatcher.group(5);
            
            // 验证版本
            if (!"2.0".equals(version)) {
                throw new IllegalArgumentException("Unsupported MRCP version: " + version);
            }
            
            log.debug("Parsed MRCP response - Version: {}, Length: {}, RequestId: {}, StatusCode: {}, StatusReason: {}", 
                    version, messageLength, requestId, statusCode, statusReason);
            
            // 解析头部，提取资源类型
            MrcpMessage.ResourceType resourceType = parseResourceTypeFromHeaders(lines);
            
            return parseResponse(statusCode, resourceType, lines, requestId);
        }
        
        // 尝试解析为事件消息
        Matcher eventMatcher = EVENT_FIRST_LINE_PATTERN.matcher(firstLine);
        if (eventMatcher.matches()) {
            String version = eventMatcher.group(1);
            String messageLength = eventMatcher.group(2);
            String eventName = eventMatcher.group(3);
            String requestId = eventMatcher.group(4);
            String requestState = eventMatcher.group(5);
            
            // 验证版本
            if (!"2.0".equals(version)) {
                throw new IllegalArgumentException("Unsupported MRCP version: " + version);
            }
            
            log.debug("Parsed MRCP event - Version: {}, Length: {}, EventName: {}, RequestId: {}, RequestState: {}", 
                    version, messageLength, eventName, requestId, requestState);
            
            // 解析头部，提取资源类型
            MrcpMessage.ResourceType resourceType = parseResourceTypeFromHeaders(lines);
            
            return parseEvent(eventName, resourceType, lines, requestId);
        }
        
        throw new IllegalArgumentException("Cannot parse MRCP message first line: " + firstLine);
    }
    
    /**
     * 解析请求消息
     */
    private static MrcpRequest parseRequest(String method, MrcpMessage.ResourceType resourceType, String[] lines, String requestId) {
        MrcpRequest request = new MrcpRequest();
        request.setResourceType(resourceType);
        request.setMethod(MrcpRequest.Method.fromString(method));
        request.setRequestId(requestId);
        
        parseHeadersAndBody(request, lines);
        return request;
    }
    
    /**
     * 解析响应消息
     */
    private static MrcpResponse parseResponse(String statusCode, MrcpMessage.ResourceType resourceType, String[] lines, String requestId) {
        int statusCodeInt = Integer.parseInt(statusCode);
        
        MrcpResponse response = new MrcpResponse();
        response.setResourceType(resourceType);
        response.setStatusCode(MrcpResponse.StatusCode.fromCode(statusCodeInt));
        response.setRequestId(requestId);
        
        parseHeadersAndBody(response, lines);
        return response;
    }
    
    /**
     * 解析事件消息
     */
    private static MrcpEvent parseEvent(String eventName, MrcpMessage.ResourceType resourceType, String[] lines, String requestId) {
        MrcpEvent event = new MrcpEvent();
        event.setResourceType(resourceType);
        event.setEventType(MrcpEvent.EventType.fromString(eventName));
        event.setRequestId(requestId);
        
        parseHeadersAndBody(event, lines);
        return event;
    }
    
    /**
     * 解析头部字段和消息体
     */
    private static void parseHeadersAndBody(MrcpMessage message, String[] lines) {
        Map<String, String> headers = new HashMap<>();
        StringBuilder body = new StringBuilder();
        boolean inBody = false;
        
        for (int i = 1; i < lines.length; i++) {
            String line = lines[i];
            
            if (line.trim().isEmpty()) {
                inBody = true;
                continue;
            }
            
            if (inBody) {
                body.append(line).append("\r\n");
            } else {
                Matcher headerMatcher = HEADER_PATTERN.matcher(line);
                if (headerMatcher.matches()) {
                    String name = headerMatcher.group(1).trim();
                    String value = headerMatcher.group(2).trim();
                    headers.put(name, value);
                    
                    // 设置特殊头部字段
                    switch (name) {
                        case "MRCP-Request-ID":
                            message.setRequestId(value);
                            break;
                        case "Session-Id":
                            message.setSessionId(value);
                            break;
                        case "Content-Type":
                            message.setContentType(value);
                            break;
                        case "Content-Length":
                            try {
                                message.setContentLength(Integer.parseInt(value));
                            } catch (NumberFormatException e) {
                                log.warn("Invalid Content-Length: {}", value);
                            }
                            break;
                    }
                }
            }
        }
        
        // 设置头部和消息体
        message.setHeaders(headers);
        if (body.length() > 0) {
            message.setBody(body.toString().trim());
        }
    }
    
    /**
     * 解析头部，提取资源类型
     */
    private static MrcpMessage.ResourceType parseResourceTypeFromHeaders(String[] lines) {
        for (int i = 1; i < lines.length; i++) {
            String line = lines[i];
            Matcher headerMatcher = HEADER_PATTERN.matcher(line);
            if (headerMatcher.matches()) {
                String name = headerMatcher.group(1).trim();
                if (name.equalsIgnoreCase("Channel-Identifier")) {
                    String value = headerMatcher.group(2).trim();
                    // Channel-Identifier格式: channelId@resourceType
                    if (value.contains("@")) {
                        String resourceTypeStr = value.split("@")[1];
                        try {
                            return MrcpMessage.ResourceType.fromString(resourceTypeStr);
                        } catch (IllegalArgumentException e) {
                            log.warn("Unknown resource type in Channel-Identifier: {}", resourceTypeStr);
                        }
                    }
                }
            }
        }
        // 如果没有找到Channel-Identifier或无法解析，则默认是语音识别
        return MrcpMessage.ResourceType.SPEECHRECOG;
    }

    /**
     * 判断是否为请求方法
     */
    private static boolean isRequestMethod(String method) {
        try {
            MrcpRequest.Method.fromString(method);
            return true;
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
    
    /**
     * 判断是否为事件类型
     */
    private static boolean isEventType(String eventType) {
        try {
            MrcpEvent.EventType.fromString(eventType);
            return true;
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
    
    /**
     * 判断是否为响应状态行
     */
    private static boolean isResponseStatus(String statusLine) {
        return statusLine.matches("^\\d+\\.\\d+\\s+\\d+\\s+.+$");
    }
}
